package com.example.handheld4_gsignal_app.services;

import android.content.Context;
import android.util.Log;
import com.example.handheld4_gsignal_app.network.ApiClient;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.*;

/**
 * 设备管理服务 - 提供设备注册、状态监控、参数配置等功能
 */
public class DeviceManagementService {
    
    private static final String TAG = "DeviceManagementService";
    private Context context;
    private ApiClient apiClient;
    private Gson gson;
    
    public DeviceManagementService(Context context) {
        this.context = context;
        this.apiClient = new ApiClient();
        this.gson = new Gson();
    }
    
    /**
     * 设备状态枚举
     */
    public enum DeviceStatus {
        ACTIVE("active"),
        INACTIVE("inactive"),
        MAINTENANCE("maintenance"),
        ERROR("error");
        
        private final String value;
        
        DeviceStatus(String value) {
            this.value = value;
        }
        
        public String getValue() {
            return value;
        }
    }
    
    /**
     * 设备模型
     */
    public static class Device {
        private String deviceId;
        private String deviceName;
        private String deviceModel;
        private String teamId;
        private String ownerId;
        private String osVersion;
        private String appVersion;
        private String firmwareVersion;
        private String hardwareVersion;
        private String status;
        private String lastSeen;
        private Integer batteryLevel;
        private Double temperature;
        private Double storageUsage;
        private Double cpuUsage;
        private Double memoryUsage;
        private Double locationLatitude;
        private Double locationLongitude;
        private Double locationAccuracy;
        private Boolean isActive;
        private String createdAt;
        private String updatedAt;
        
        // Getters and Setters
        public String getDeviceId() { return deviceId; }
        public void setDeviceId(String deviceId) { this.deviceId = deviceId; }
        
        public String getDeviceName() { return deviceName; }
        public void setDeviceName(String deviceName) { this.deviceName = deviceName; }
        
        public String getDeviceModel() { return deviceModel; }
        public void setDeviceModel(String deviceModel) { this.deviceModel = deviceModel; }
        
        public String getTeamId() { return teamId; }
        public void setTeamId(String teamId) { this.teamId = teamId; }
        
        public String getOwnerId() { return ownerId; }
        public void setOwnerId(String ownerId) { this.ownerId = ownerId; }
        
        public String getOsVersion() { return osVersion; }
        public void setOsVersion(String osVersion) { this.osVersion = osVersion; }
        
        public String getAppVersion() { return appVersion; }
        public void setAppVersion(String appVersion) { this.appVersion = appVersion; }
        
        public String getFirmwareVersion() { return firmwareVersion; }
        public void setFirmwareVersion(String firmwareVersion) { this.firmwareVersion = firmwareVersion; }
        
        public String getHardwareVersion() { return hardwareVersion; }
        public void setHardwareVersion(String hardwareVersion) { this.hardwareVersion = hardwareVersion; }
        
        public String getStatus() { return status; }
        public void setStatus(String status) { this.status = status; }
        
        public String getLastSeen() { return lastSeen; }
        public void setLastSeen(String lastSeen) { this.lastSeen = lastSeen; }
        
        public Integer getBatteryLevel() { return batteryLevel; }
        public void setBatteryLevel(Integer batteryLevel) { this.batteryLevel = batteryLevel; }
        
        public Double getTemperature() { return temperature; }
        public void setTemperature(Double temperature) { this.temperature = temperature; }
        
        public Double getStorageUsage() { return storageUsage; }
        public void setStorageUsage(Double storageUsage) { this.storageUsage = storageUsage; }
        
        public Double getCpuUsage() { return cpuUsage; }
        public void setCpuUsage(Double cpuUsage) { this.cpuUsage = cpuUsage; }
        
        public Double getMemoryUsage() { return memoryUsage; }
        public void setMemoryUsage(Double memoryUsage) { this.memoryUsage = memoryUsage; }
        
        public Double getLocationLatitude() { return locationLatitude; }
        public void setLocationLatitude(Double locationLatitude) { this.locationLatitude = locationLatitude; }
        
        public Double getLocationLongitude() { return locationLongitude; }
        public void setLocationLongitude(Double locationLongitude) { this.locationLongitude = locationLongitude; }
        
        public Double getLocationAccuracy() { return locationAccuracy; }
        public void setLocationAccuracy(Double locationAccuracy) { this.locationAccuracy = locationAccuracy; }
        
        public Boolean getIsActive() { return isActive; }
        public void setIsActive(Boolean isActive) { this.isActive = isActive; }
        
        public String getCreatedAt() { return createdAt; }
        public void setCreatedAt(String createdAt) { this.createdAt = createdAt; }
        
        public String getUpdatedAt() { return updatedAt; }
        public void setUpdatedAt(String updatedAt) { this.updatedAt = updatedAt; }
    }
    
    /**
     * 设备状态更新请求
     */
    public static class DeviceStatusUpdate {
        private String deviceId;
        private String status;
        private Integer batteryLevel;
        private Double temperature;
        private Double storageUsage;
        private Double cpuUsage;
        private Double memoryUsage;
        private Double locationLatitude;
        private Double locationLongitude;
        private Double locationAccuracy;
        
        public DeviceStatusUpdate(String deviceId) {
            this.deviceId = deviceId;
        }
        
        // Getters and Setters
        public String getDeviceId() { return deviceId; }
        public void setDeviceId(String deviceId) { this.deviceId = deviceId; }
        
        public String getStatus() { return status; }
        public void setStatus(String status) { this.status = status; }
        
        public Integer getBatteryLevel() { return batteryLevel; }
        public void setBatteryLevel(Integer batteryLevel) { this.batteryLevel = batteryLevel; }
        
        public Double getTemperature() { return temperature; }
        public void setTemperature(Double temperature) { this.temperature = temperature; }
        
        public Double getStorageUsage() { return storageUsage; }
        public void setStorageUsage(Double storageUsage) { this.storageUsage = storageUsage; }
        
        public Double getCpuUsage() { return cpuUsage; }
        public void setCpuUsage(Double cpuUsage) { this.cpuUsage = cpuUsage; }
        
        public Double getMemoryUsage() { return memoryUsage; }
        public void setMemoryUsage(Double memoryUsage) { this.memoryUsage = memoryUsage; }
        
        public Double getLocationLatitude() { return locationLatitude; }
        public void setLocationLatitude(Double locationLatitude) { this.locationLatitude = locationLatitude; }
        
        public Double getLocationLongitude() { return locationLongitude; }
        public void setLocationLongitude(Double locationLongitude) { this.locationLongitude = locationLongitude; }
        
        public Double getLocationAccuracy() { return locationAccuracy; }
        public void setLocationAccuracy(Double locationAccuracy) { this.locationAccuracy = locationAccuracy; }
    }
    
    /**
     * 设备注册请求
     */
    public static class DeviceRegistrationRequest {
        private String deviceId;
        private String deviceName;
        private String deviceModel;
        private String teamId;
        private String osVersion;
        private String appVersion;
        private String firmwareVersion;
        private String hardwareVersion;
        
        public DeviceRegistrationRequest(String deviceId, String deviceName, String teamId) {
            this.deviceId = deviceId;
            this.deviceName = deviceName;
            this.teamId = teamId;
        }
        
        // Getters and Setters
        public String getDeviceId() { return deviceId; }
        public void setDeviceId(String deviceId) { this.deviceId = deviceId; }
        
        public String getDeviceName() { return deviceName; }
        public void setDeviceName(String deviceName) { this.deviceName = deviceName; }
        
        public String getDeviceModel() { return deviceModel; }
        public void setDeviceModel(String deviceModel) { this.deviceModel = deviceModel; }
        
        public String getTeamId() { return teamId; }
        public void setTeamId(String teamId) { this.teamId = teamId; }
        
        public String getOsVersion() { return osVersion; }
        public void setOsVersion(String osVersion) { this.osVersion = osVersion; }
        
        public String getAppVersion() { return appVersion; }
        public void setAppVersion(String appVersion) { this.appVersion = appVersion; }
        
        public String getFirmwareVersion() { return firmwareVersion; }
        public void setFirmwareVersion(String firmwareVersion) { this.firmwareVersion = firmwareVersion; }
        
        public String getHardwareVersion() { return hardwareVersion; }
        public void setHardwareVersion(String hardwareVersion) { this.hardwareVersion = hardwareVersion; }
    }
    
    /**
     * 设备列表响应
     */
    public static class DeviceListResponse {
        private List<Device> devices;
        private int total;
        private int page;
        private int pageSize;
        private int totalPages;
        
        // Getters and Setters
        public List<Device> getDevices() { return devices; }
        public void setDevices(List<Device> devices) { this.devices = devices; }
        
        public int getTotal() { return total; }
        public void setTotal(int total) { this.total = total; }
        
        public int getPage() { return page; }
        public void setPage(int page) { this.page = page; }
        
        public int getPageSize() { return pageSize; }
        public void setPageSize(int pageSize) { this.pageSize = pageSize; }
        
        public int getTotalPages() { return totalPages; }
        public void setTotalPages(int totalPages) { this.totalPages = totalPages; }
    }
    
    /**
     * 设备告警
     */
    public static class DeviceAlert {
        private String deviceId;
        private String deviceName;
        private String alertType;
        private String severity;
        private String message;
        private String timestamp;
        
        // Getters and Setters
        public String getDeviceId() { return deviceId; }
        public void setDeviceId(String deviceId) { this.deviceId = deviceId; }
        
        public String getDeviceName() { return deviceName; }
        public void setDeviceName(String deviceName) { this.deviceName = deviceName; }
        
        public String getAlertType() { return alertType; }
        public void setAlertType(String alertType) { this.alertType = alertType; }
        
        public String getSeverity() { return severity; }
        public void setSeverity(String severity) { this.severity = severity; }
        
        public String getMessage() { return message; }
        public void setMessage(String message) { this.message = message; }
        
        public String getTimestamp() { return timestamp; }
        public void setTimestamp(String timestamp) { this.timestamp = timestamp; }
    }
    
    /**
     * 回调接口
     */
    public interface DeviceCallback {
        void onSuccess(Device device);
        void onError(String error);
    }
    
    public interface DeviceListCallback {
        void onSuccess(DeviceListResponse response);
        void onError(String error);
    }
    
    public interface DeviceAlertsCallback {
        void onSuccess(List<DeviceAlert> alerts);
        void onError(String error);
    }
    
    public interface ConfigCallback {
        void onSuccess(Map<String, Object> config);
        void onError(String error);
    }
    
    /**
     * 注册设备
     */
    public void registerDevice(DeviceRegistrationRequest request, DeviceCallback callback) {
        try {
            String requestJson = gson.toJson(request);
            Log.d(TAG, "设备注册请求: " + request.getDeviceId());
            
            apiClient.post("/api/v2/devices", requestJson, new ApiClient.ApiCallback() {
                @Override
                public void onSuccess(String response) {
                    try {
                        Device device = gson.fromJson(response, Device.class);
                        Log.d(TAG, "设备注册成功: " + device.getDeviceId());
                        callback.onSuccess(device);
                    } catch (Exception e) {
                        Log.e(TAG, "解析设备注册结果失败", e);
                        callback.onError("解析结果失败: " + e.getMessage());
                    }
                }
                
                @Override
                public void onError(String error) {
                    Log.e(TAG, "设备注册失败: " + error);
                    callback.onError(error);
                }
            });
            
        } catch (Exception e) {
            Log.e(TAG, "设备注册请求失败", e);
            callback.onError("注册请求失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取设备信息
     */
    public void getDevice(String deviceId, DeviceCallback callback) {
        try {
            String url = "/api/v2/devices/" + deviceId;
            Log.d(TAG, "获取设备信息: " + deviceId);
            
            apiClient.get(url, new ApiClient.ApiCallback() {
                @Override
                public void onSuccess(String response) {
                    try {
                        Device device = gson.fromJson(response, Device.class);
                        Log.d(TAG, "获取设备信息成功: " + device.getDeviceName());
                        callback.onSuccess(device);
                    } catch (Exception e) {
                        Log.e(TAG, "解析设备信息失败", e);
                        callback.onError("解析结果失败: " + e.getMessage());
                    }
                }
                
                @Override
                public void onError(String error) {
                    Log.e(TAG, "获取设备信息失败: " + error);
                    callback.onError(error);
                }
            });
            
        } catch (Exception e) {
            Log.e(TAG, "获取设备信息请求失败", e);
            callback.onError("获取请求失败: " + e.getMessage());
        }
    }
    
    /**
     * 更新设备状态
     */
    public void updateDeviceStatus(DeviceStatusUpdate statusUpdate, DeviceCallback callback) {
        try {
            String requestJson = gson.toJson(statusUpdate);
            String url = "/api/v2/devices/" + statusUpdate.getDeviceId() + "/status";
            Log.d(TAG, "更新设备状态: " + statusUpdate.getDeviceId());
            
            apiClient.put(url, requestJson, new ApiClient.ApiCallback() {
                @Override
                public void onSuccess(String response) {
                    try {
                        Device device = gson.fromJson(response, Device.class);
                        Log.d(TAG, "设备状态更新成功: " + device.getDeviceId());
                        callback.onSuccess(device);
                    } catch (Exception e) {
                        Log.e(TAG, "解析设备状态更新结果失败", e);
                        callback.onError("解析结果失败: " + e.getMessage());
                    }
                }
                
                @Override
                public void onError(String error) {
                    Log.e(TAG, "设备状态更新失败: " + error);
                    callback.onError(error);
                }
            });
            
        } catch (Exception e) {
            Log.e(TAG, "设备状态更新请求失败", e);
            callback.onError("更新请求失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取团队设备列表
     */
    public void getTeamDevices(String status, int page, int pageSize, DeviceListCallback callback) {
        try {
            StringBuilder url = new StringBuilder("/api/v2/devices?");
            if (status != null) url.append("status=").append(status).append("&");
            url.append("page=").append(page).append("&");
            url.append("page_size=").append(pageSize);
            
            Log.d(TAG, "获取团队设备列表: " + url.toString());
            
            apiClient.get(url.toString(), new ApiClient.ApiCallback() {
                @Override
                public void onSuccess(String response) {
                    try {
                        DeviceListResponse deviceList = gson.fromJson(response, DeviceListResponse.class);
                        Log.d(TAG, "获取团队设备列表成功，数量: " + deviceList.getDevices().size());
                        callback.onSuccess(deviceList);
                    } catch (Exception e) {
                        Log.e(TAG, "解析团队设备列表失败", e);
                        callback.onError("解析结果失败: " + e.getMessage());
                    }
                }
                
                @Override
                public void onError(String error) {
                    Log.e(TAG, "获取团队设备列表失败: " + error);
                    callback.onError(error);
                }
            });
            
        } catch (Exception e) {
            Log.e(TAG, "获取团队设备列表请求失败", e);
            callback.onError("获取请求失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取离线设备列表
     */
    public void getOfflineDevices(int offlineThresholdMinutes, DeviceListCallback callback) {
        try {
            String url = "/api/v2/devices/offline?offline_threshold_minutes=" + offlineThresholdMinutes;
            Log.d(TAG, "获取离线设备列表: " + url);
            
            apiClient.get(url, new ApiClient.ApiCallback() {
                @Override
                public void onSuccess(String response) {
                    try {
                        Type listType = new TypeToken<List<Device>>(){}.getType();
                        List<Device> devices = gson.fromJson(response, listType);
                        
                        DeviceListResponse response_obj = new DeviceListResponse();
                        response_obj.setDevices(devices);
                        response_obj.setTotal(devices.size());
                        
                        Log.d(TAG, "获取离线设备列表成功，数量: " + devices.size());
                        callback.onSuccess(response_obj);
                    } catch (Exception e) {
                        Log.e(TAG, "解析离线设备列表失败", e);
                        callback.onError("解析结果失败: " + e.getMessage());
                    }
                }
                
                @Override
                public void onError(String error) {
                    Log.e(TAG, "获取离线设备列表失败: " + error);
                    callback.onError(error);
                }
            });
            
        } catch (Exception e) {
            Log.e(TAG, "获取离线设备列表请求失败", e);
            callback.onError("获取请求失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取设备告警
     */
    public void getDeviceAlerts(DeviceAlertsCallback callback) {
        try {
            String url = "/api/v2/devices/alerts";
            Log.d(TAG, "获取设备告警: " + url);
            
            apiClient.get(url, new ApiClient.ApiCallback() {
                @Override
                public void onSuccess(String response) {
                    try {
                        Type listType = new TypeToken<List<DeviceAlert>>(){}.getType();
                        List<DeviceAlert> alerts = gson.fromJson(response, listType);
                        Log.d(TAG, "获取设备告警成功，数量: " + alerts.size());
                        callback.onSuccess(alerts);
                    } catch (Exception e) {
                        Log.e(TAG, "解析设备告警失败", e);
                        callback.onError("解析结果失败: " + e.getMessage());
                    }
                }
                
                @Override
                public void onError(String error) {
                    Log.e(TAG, "获取设备告警失败: " + error);
                    callback.onError(error);
                }
            });
            
        } catch (Exception e) {
            Log.e(TAG, "获取设备告警请求失败", e);
            callback.onError("获取请求失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取设备配置
     */
    public void getDeviceConfig(String deviceId, ConfigCallback callback) {
        try {
            String url = "/api/v2/devices/" + deviceId + "/config";
            Log.d(TAG, "获取设备配置: " + deviceId);
            
            apiClient.get(url, new ApiClient.ApiCallback() {
                @Override
                public void onSuccess(String response) {
                    try {
                        Type mapType = new TypeToken<Map<String, Object>>(){}.getType();
                        Map<String, Object> config = gson.fromJson(response, mapType);
                        Log.d(TAG, "获取设备配置成功");
                        callback.onSuccess(config);
                    } catch (Exception e) {
                        Log.e(TAG, "解析设备配置失败", e);
                        callback.onError("解析结果失败: " + e.getMessage());
                    }
                }
                
                @Override
                public void onError(String error) {
                    Log.e(TAG, "获取设备配置失败: " + error);
                    callback.onError(error);
                }
            });
            
        } catch (Exception e) {
            Log.e(TAG, "获取设备配置请求失败", e);
            callback.onError("获取请求失败: " + e.getMessage());
        }
    }
    
    /**
     * 更新设备配置
     */
    public void updateDeviceConfig(String deviceId, Map<String, Object> config, DeviceCallback callback) {
        try {
            String requestJson = gson.toJson(config);
            String url = "/api/v2/devices/" + deviceId + "/config";
            Log.d(TAG, "更新设备配置: " + deviceId);
            
            apiClient.put(url, requestJson, new ApiClient.ApiCallback() {
                @Override
                public void onSuccess(String response) {
                    try {
                        // 配置更新成功，返回成功消息
                        Log.d(TAG, "设备配置更新成功: " + deviceId);
                        callback.onSuccess(null); // 配置更新不返回设备对象
                    } catch (Exception e) {
                        Log.e(TAG, "解析设备配置更新结果失败", e);
                        callback.onError("解析结果失败: " + e.getMessage());
                    }
                }
                
                @Override
                public void onError(String error) {
                    Log.e(TAG, "设备配置更新失败: " + error);
                    callback.onError(error);
                }
            });
            
        } catch (Exception e) {
            Log.e(TAG, "设备配置更新请求失败", e);
            callback.onError("更新请求失败: " + e.getMessage());
        }
    }
}